<?php
class Pageley_Config_PonTests extends Pageley_Test_Case {
	private $factory;
	private $logger;
	
	public function setUp() {
		$factory = Pageley_Config::getInstance();
		$factory->addConfigLocation("dummy");
		$factory->initialize();
		$this->factory = $factory;
	}
	
	private function getLogger() {
		if($this->logger === null) {
			$logFactory = Pageley_Log_Factory::getInstance();
			$this->logger = $logFactory->getLogger($this);
		}
		return $this->logger;
	}

	public function testCreateObject() {
		$object = $this->factory->valueOf("basicDummy");
		$this->assertNotNull($object);
		$this->assertTrue($object instanceof Pageley_Config_Dummy);
	}
	
	public function testRecycleObject() {
		$object1 = $this->factory->valueOf("basicDummy");
		$object2 = $this->factory->valueOf("basicDummy");
		$this->assertSame($object1, $object2);
	}
	
	public function testInjectBasicProperty() {
		$object = $this->factory->valueOf("dummyWithBasicProperty");
		$this->assertEquals("dummyValue", $object->getProperty());
	}
	
	public function testInjectCollectionProperty() {
		$object = $this->factory->valueOf("dummyWithCollectionProperty");
		$property = $object->getProperty();
		$this->assertTrue($property instanceof Pageley_Util_Map);
		$this->assertEquals("value1", $property->get("key1"));
		$this->assertEquals("value2", $property->get("key2"));
		$this->assertEquals("value3", $property->get("key3"));
	}
	
	public function testInjectReferenceProperty() {
		$object = $this->factory->valueOf("dummyWithReferenceProperty");
		$property = $object->getProperty();
		$this->assertNotNull($property);
		$this->assertTrue($property instanceof Pageley_Config_Dummy);
	}
	
	public function testInjectReferenceInCollectionProperty() {
		$object = $this->factory->valueOf("dummyWithReferenceInCollectionProperty");
		$property = $object->getProperty();
		$this->assertTrue($property instanceof Pageley_Util_Map);
		$this->assertNotNull($property->get("key1"));
		$this->assertTrue($property->get("key1") instanceof Pageley_Config_Dummy);
		$this->assertEquals("value2", $property->get("key2"));
	}
	
	public function testInjectNestedReferenceProperty() {
		$object = $this->factory->valueOf("dummyWithNestedReferenceProperty");
		$property = $object->getProperty();
		$property = $property->getProperty();
		$this->assertNotNull($property);
		$this->assertTrue($property instanceof Pageley_Config_Dummy);
	}
	
	public function testIncorrectClass() {
		try {
			$object = $this->factory->valueOf("dummyWithIncorrectClass");
			$this->fail("Expected exception.");
		} catch(Pageley_Config_Exception $e) {
			$logger = $this->getLogger();
			if($logger->isDebugEnabled()) {
				$logger->debug("Exeption thrown: " . $e->getMessage());
			}
		}
	}
	
	public function testInjectIncorrectSetter() {
		try {
			$object = $this->factory->valueOf("dummyWithIncorrectSetter");
			$this->fail("Expected exception.");
		} catch(Pageley_Config_Exception $e) {
			$logger = $this->getLogger();
			if($logger->isDebugEnabled()) {
				$logger->debug("Exeption thrown: " . $e->getMessage());
			}
		}
	}
	
	public function testConstructorArguments() {
		$object = $this->factory->valueOf("dummyWithConstructor");
		$this->assertNotNull($object);
		$this->assertTrue($object instanceof Pageley_Config_Dummy);
		$this->assertEquals("dummyValue", $object->getProperty());
	}
	
	public function testConstructorReference() {
		$object = $this->factory->valueOf("dummyWithConstructorReference");
		$this->assertNotNull($object);
		$this->assertTrue($object instanceof Pageley_Config_Dummy);
		$property = $object->getProperty();
		$this->assertNotNull($property);
		$this->assertTrue($property instanceof Pageley_Config_Dummy);
	}
	
	public function testFactoryMethod() {
		$object = $this->factory->valueOf("dummyWithFactoryMethod");
		$this->assertNotNull($object);
		$this->assertTrue($object instanceof Pageley_Config_Dummy);
		$this->assertEquals("factoryMethod", $object->getProperty());
	}
	
	public function testCircularReference() {
		$object = $this->factory->valueOf("dummyWithCircularReference");
		$this->assertEquals($object, $object->getProperty());
	}
	
	public function testCircularConstructorReference() {
		try {
			$object = $this->factory->valueOf("dummyWithCircularConstructorReference");
			$this->fail("Expected exception.");
		} catch(Pageley_Config_Exception $e) {
			$logger = $this->getLogger();
			if($logger->isDebugEnabled()) {
				$logger->debug("Exeption thrown: " . $e->getMessage());
			}
		}
	}

	public function testNonExistingReference() {
		try {
			$object = $this->factory->valueOf("nonExistingDummy");
			$this->fail("Expected exception.");
		} catch(Pageley_Config_Exception $e) {
			$logger = $this->getLogger();
			if($logger->isDebugEnabled()) {
				$logger->debug("Exeption thrown: " . $e->getMessage());
			}
		}
	}
	
	public function testDecorator() {
	    $decorated = $this->factory->valueOf("decoratedDummy");
	    $decorating = $this->factory->valueOf("decoratingDummy");
	    $basic = $this->factory->valueOf("basicDummy");
        $this->assertEquals($decorating, $decorated->getProperty());
        $this->assertEquals($basic, $decorating->getProperty());
        $this->assertEquals("decorating", $decorating->getOtherProperty());
	}
}